/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * File Name          : freertos.c
 * Description        : Code for freertos applications
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "SEGGER_RTT.h"
#include "bsp_key.h"
#include "elog.h"
#include "queue.h"
#include "w25qxx.h"
#include "usart.h"

#include "ota.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define TAG "rtos"
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
osThreadId_t KeyTaskHandle;
const osThreadAttr_t KeyTask_attributes = {
    .name = "KeyTask",
    .stack_size = 128 * 4,
    .priority = (osPriority_t)osPriorityNormal,
};
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for myBinarySem01 */
osSemaphoreId_t myBinarySem01Handle;
const osSemaphoreAttr_t myBinarySem01_attributes = {
  .name = "myBinarySem01"
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void KeyTask(void* argument);
QueueHandle_t key_queue;

uint8_t rec_cmd[10];
uint16_t rec_len=0;

extern QueueHandle_t Q_YmodemReclength;
extern osThreadAttr_t OTA_task_attributes;
extern osThreadId_t OTA_taskHandle;
/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* Create the semaphores(s) */
  /* creation of myBinarySem01 */
  myBinarySem01Handle = osSemaphoreNew(1, 1, &myBinarySem01_attributes);

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
	Q_YmodemReclength = xQueueCreate(2,sizeof(uint16_t));
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  KeyTaskHandle = osThreadNew(KeyTask, NULL, &KeyTask_attributes);
  OTA_taskHandle = osThreadNew(ota_task_runnable, NULL, &OTA_task_attributes);
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
 * @brief  Function implementing the defaultTask thread.
 * @param  argument: Not used
 * @retval None
 */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  // char strbuff[64];
//  uint8_t e;
	// HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rec_cmd,10);
  /* Infinite loop */
  for (;;)
  {
    // osDelay(1);
//		HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
//		vTaskDelay(500);
		HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    HAL_GPIO_TogglePin(LCD_BL_GPIO_Port, LCD_BL_Pin);
		vTaskDelay(1000);
// 		if(rec_len!=0)
// 		{
// 			for(int i=0;i<rec_len;i++)
// 			{
// 				HAL_UART_Transmit(&huart1,&rec_cmd[i],1,10);
// 			}
// 			rec_len=0;
// 			HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rec_cmd,10);
// //			elog_i(TAG,"REC:[%s]",rec_cmd);
// 		}

  //  if (key_queue != NULL)
  //  {
  //    if (xQueueReceive(key_queue, &e, 100))
  //    {
  //      elog_i(TAG, "key.event [%d][RECEIVE]", e);
  //      HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  //      HAL_GPIO_TogglePin(LCD_BL_GPIO_Port, LCD_BL_Pin);
  //    }
  //  }
  //  vTaskDelay(100);
    // elog_i(TAG,"Hello world");
    // SEGGER_RTT_printf(0,"%s","hello world\n");
    // vTaskDelay(1000);
  }
  /* USER CODE END StartDefaultTask */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
extern DMA_HandleTypeDef hdma_usart1_rx;
/**
 * @brief  UART 接收事件回调函数
 * @param  huart 指向 UART 句柄的指针
 * @param  Size  接收到的数据大小
 * @retval 无
 * @note   该函数在 UART 接收事件（如空闲帧检测）发生时由 HAL 库自动调用
 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  UNUSED(Size);

  uint16_t t_u16_rec_len = 0;
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_UARTEx_RxEventCallback can be implemented in the user file.
   */
	if(huart->Instance == USART1)
	{
		if(1==__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE))
		{
			t_u16_rec_len = Size;
        if(pdFALSE != xQueueSendFromISR(Q_YmodemReclength,&t_u16_rec_len,0))
				{
					xHigherPriorityTaskWoken = pdTRUE; 
				}
				HAL_UART_DMAStop(huart);
		}
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);// 通知调度器切换任务
	}
}
void KeyTask(void* argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  bsp_key_init(&key);
  key_queue = xQueueCreate(10, sizeof(uint8_t));
  /* Infinite loop */
  for (;;)
  {
    bsp_key_proc(&key);
    		// if (key.event == KEY_EVENT_PRESS)
        // {
        //   elog_i(TAG, "KEY_EVENT_PRESS\r\n");
        //   key.event = KEY_EVENT_NONE;
    		// }
    		// if (key.event == KEY_EVENT_DOUBLE_CLICK)
        // {
        //   elog_i(TAG, "KEY_EVENT_DOUBLE_CLICK\r\n");
        //   key.event = KEY_EVENT_NONE;
    		// }
   if (key.key_status ==1 && key.event != KEY_EVENT_NONE)
   {
     if (pdPASS == xQueueSendToFront(key_queue, &key.event, 0))
     {
       elog_w(TAG, "key.event [%d][SEND]", key.event);
     }
     key.event = KEY_EVENT_NONE;
   }
    vTaskDelay(10);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE END Application */

